package com.yupi.project.handler;

import com.yupi.project.model.AuthenticatorResult;
import com.yupi.project.model.ProtectedRequest;
import com.yupi.project.model.RequestHolder;
import com.yupi.project.model.RequestInfo;
import com.yupi.project.security.SecurityVerificationHandler;
import com.yupi.yuapicommon.model.entity.InterfaceInfo;
import com.yupi.yuapicommon.model.entity.User;
import com.yupi.yuapicommon.service.InnerInterfaceInfoService;
import com.yupi.yuapicommon.service.InnerUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @description: 校验用户和接口是否存在
 * @author SummerBird
 * @date 2024/3/8 18:29
 * @version 1.0
 */
@Component
@Slf4j
public class CheckBaseInfoHandler implements SecurityVerificationHandler {

    @DubboReference
    private InnerUserService innerUserService;

    @DubboReference
    private InnerInterfaceInfoService innerInterfaceInfoService;

    @Override
    public AuthenticatorResult auth(ProtectedRequest protectedRequest) {
        // 将后续需要反复使用的信息放入ThreadLocal中
        // 校验接口是否存在
        if(!checkInterfaceInfo(protectedRequest.getRequest())){
            return AuthenticatorResult.fail("请求接口不存在");
        }
        // 校验用户是否存在
        if(!checkUser(protectedRequest.getRequest())){
            return AuthenticatorResult.fail("请求用户不存在");
        }
        return AuthenticatorResult.success();
    }

    private boolean checkInterfaceInfo(ServerHttpRequest request) {
        String path = request.getURI().toString();
        String method = request.getMethod().name();
        // 请求的模拟接口是否存在?
        //从数据库中查询模拟接口是否存在，以及请求方法是否匹配（还可以校验参数）
        InterfaceInfo interfaceInfo = null;
        try {
            int index = path.indexOf("?");
            interfaceInfo = innerInterfaceInfoService.getInterfaceInfo(path.substring(0,  index == -1 ? path.length() : index), method);
        } catch (Exception e){
            log.error("getInterfaceInfo error", e);
        }
        if(Objects.isNull(interfaceInfo)){
            return false;
        }
        RequestHolder.get().setInterfaceInvokeInfo(RequestInfo.buildInterfaceInvokeInfo(interfaceInfo));
        return true;
    }

    private boolean checkUser(ServerHttpRequest request) {
        User invokeUser = null;
        try {
            invokeUser = innerUserService.getInvokeUser(RequestHolder.get().getAccessKey());
        }catch (Exception e){
            log.error("getinvokeUser error", e);
        }
        if(Objects.isNull(invokeUser)){
            return false;
        }
        RequestHolder.get().setUserInfo(RequestInfo.buildUserInfo(invokeUser));
        return true;
    }

    @Override
    public int getOrder() {
        return 3;
    }
}
